#K-均值聚类
#计算聚类过程中的轮廓系数
import pandas as pd

# 导入数据
data = pd.read_csv(
    "http://labfile.oss.aliyuncs.com/courses/764/three_class_data.csv", header=0)
data.head()

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from matplotlib import pyplot as plt

X = data[["x", "y"]]
score = []  # 建立模型

# 依次计算 2 到 12 类的轮廓系数
for i in range(10):
    model = KMeans(n_clusters=i+2,n_init=10)#开始的时候没有加上n_init=10，导致报错
    model.fit(X)
    score.append(silhouette_score(X, model.labels_))

plt.figure(figsize=(11, 5))
plt.subplot(1, 2, 1)
plt.scatter(data['x'], data['y'])
plt.subplot(1, 2, 2)
plt.plot(range(2, 12, 1), score)
plt.show()#得出结论 3 是最好的

model = KMeans(n_clusters=3,n_init=10)
model.fit(X)
plt.scatter(data['x'], data['y'], c=model.labels_)
#绘制出 k-均值聚类的决策边界
import numpy as np

# 计算聚类过程中的决策边界
x_min, x_max = data['x'].min() - 0.1, data['x'].max() + 0.1
y_min, y_max = data['y'].min() - 0.1, data['y'].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, .01),
                     np.arange(y_min, y_max, .01))

result = model.predict(np.c_[xx.ravel(), yy.ravel()])

# 将决策边界绘制绘制出来
result = result.reshape(xx.shape)
plt.contourf(xx, yy, result, cmap=plt.cm.Greens)
plt.scatter(data['x'], data['y'], c=model.labels_, s=15)
# 绘制聚类中心点
center = model.cluster_centers_
plt.scatter(center[:, 0], center[:, 1], marker='p',
            linewidths=2, color='b', edgecolors='w', zorder=20)
plt.show()
#会报一个错误
#解决办法
# import warnings
# from sklearn.cluster import KMeans
#
# # 忽略警告信息
# warnings.filterwarnings('ignore', message="X does not have valid feature names, but KMeans was fitted with feature names")

#网上找到的其他聚类方法
"""from sklearn import cluster
import time

# 对聚类方法依次命名
cluster_names = ['KMeans', 'MiniBatchKMeans', 'AffinityPropagation', 'MeanShift',
                 'SpectralClustering', 'AgglomerativeClustering', 'Birch', 'DBSCAN']

# 确定聚类方法相应参数
cluster_estimators = [
    cluster.KMeans(n_clusters=3),
    cluster.MiniBatchKMeans(n_clusters=3),
    cluster.AffinityPropagation(),
    cluster.MeanShift(),
    cluster.SpectralClustering(n_clusters=3),
    cluster.AgglomerativeClustering(n_clusters=3),
    cluster.Birch(n_clusters=3, threshold=0.1),
    cluster.DBSCAN()
]

# 为绘制子图准备
plot_num = 1
plt.figure(figsize=(14, 7))
# 依次运行不同的聚类方法
for name, model in zip(cluster_names, cluster_estimators):
    tic = time.time()
    # 建立模型
    model.fit(X)
    # 绘制子图
    plt.subplot(2, len(cluster_estimators) / 2, plot_num)
    # 计算聚类过程中的决策边界
    x_min, x_max = data['x'].min() - 0.1, data['x'].max() + 0.1
    y_min, y_max = data['y'].min() - 0.1, data['y'].max() + 0.1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, .01),
                         np.arange(y_min, y_max, .01))
    if hasattr(model, 'predict'):
        result = model.predict(np.c_[xx.ravel(), yy.ravel()])
        # 将决策边界绘制绘制出来
        result = result.reshape(xx.shape)
        plt.contourf(xx, yy, result, cmap=plt.cm.Greens)

    plt.scatter(data['x'], data['y'], c=model.labels_, s=15)
    # 判断方法中是否由 cluster_centers_ 聚类中心参数，并执行不同的命令
    if hasattr(model, 'cluster_centers_'):
        center = model.cluster_centers_
        plt.scatter(center[:, 0], center[:, 1], marker='p',
                    linewidths=2, color='b', edgecolors='w', zorder=20)
    # 计算算法运行时间
    toc = time.time()
    cluster_time = (toc - tic)*1000
    # 绘图
    plt.title(str(name) + ", " + str(int(cluster_time)) + "ms")
    plot_num += 1"""

#如果已知𝑘值，即聚类的数量：
#样本数量 < 1 万，首选 K-Means，效果不好再选择 Spectral Clustering。
#样本数量 > 1 万，首选 MiniBatch K-Means。
# 如果𝑘值未知：
# 样本数量 < 1 万，首选 Mean Shift。
# 样本数量 > 1 万，依靠经验灵活应对了。